package com.wpzf.zxhc.controller;

import com.alibaba.fastjson.JSONObject;
import com.wpzf.common.core.utils.ServletUtils;
import com.wpzf.common.core.web.domain.AjaxResult;
import com.wpzf.common.log.annotation.Log;
import com.wpzf.common.log.enums.BusinessType;
import com.wpzf.common.security.service.TokenService;
import com.wpzf.system.api.model.LoginUser;
import com.wpzf.zxhc.utils.OBSDeleteUnits;
import com.wpzf.zxhc.utils.OBSUploadUnits;
import com.wpzf.zxhc.service.AppService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

@RestController
@RequestMapping("/app")
public class APPController {

    @Autowired
    TokenService tokenService;

    @Autowired
    AppService appService;

    /**
     * APP登录接口
     *
     * @param param
     * @return
     */

    @Log(title = "APP登录接口", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public AjaxResult Login(@RequestBody Map<String, Object> param) {
//        LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
//        return R.ok(tokenService.createToken(userInfo));
        return null;
    }

    /*获取批次号*/
    @Log(title = "获取批次号", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/queryPch", method = RequestMethod.POST)
    public AjaxResult queryPch(@RequestBody Map<String, Object> param) {
        List<Map<String, Object>> rest = appService.queryPch(param);
        if (rest != null) {
            return AjaxResult.success("获取批次号 成功", rest);
        }
        return AjaxResult.error("获取批次号 失败", -1);
    }

    /*区县列表获取接口*/
    @Log(title = "区县列表获取接口", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/queryXzqdmList", method = RequestMethod.POST)
    public AjaxResult queryXzqdmList(@RequestBody Map<String, Object> param) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        param.put("xzqdm", loginUser.getSysUser().getXzqdm());
        List<Map<String, Object>> rest = appService.queryXzqdmList(param);
        Integer cnt = appService.queryXzqdmListCount(param);
        if (rest != null) {
            return AjaxResult.success("区县列表获取接口 成功", rest, cnt);
        }
        return AjaxResult.error("区县列表获取接口 失败", -1);
    }

    /*地块列表获取接口*/
    @Log(title = "地块列表获取接口", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/queryDkTaskList", method = RequestMethod.POST)
    public AjaxResult queryDkTaskList(@RequestBody Map<String, Object> param) {
        List<Map<String, Object>> rest = appService.queryDkTaskList(param);
        Integer cnt = appService.queryDkTaskListCount(param);
        if (rest != null) {
            return AjaxResult.success("区县列表获取接口 成功", rest, cnt);
        }
        return AjaxResult.error("区县列表获取接口 失败", -1);
    }

    /**
     * 获取所有项目信息
     *
     * @param param
     * @return
     */
    @Log(title = "获取所有项目信息", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/queryProjectList", method = RequestMethod.POST)
    public AjaxResult queryProjectList(@RequestBody Map<String, Object> param) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        param.put("xzqdm", loginUser.getSysUser().getXzqdm());
        List<Map<String, Object>> rest = appService.queryProjectList(param);
        Integer cnt = appService.queryProjectListCount(param);
        if (rest != null) {
            return AjaxResult.success("获取所有项目信息 成功", rest, cnt);
        }
        return AjaxResult.error("获取所有项目信息 失败", -1);
    }

    /**
     * 获取项目下所有任务信息
     *
     * @param param
     * @return
     */
    @Log(title = "获取项目下所有任务信息", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/queryTaskList", method = RequestMethod.POST)
    public AjaxResult queryTaskList(@RequestBody Map<String, Object> param) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        param.put("xzqdm", loginUser.getSysUser().getXzqdm());
        List<Map<String, Object>> rest = appService.queryTaskList(param);
        Integer cnt = appService.queryTaskListCount(param);
        if (rest != null) {
            return AjaxResult.success("获取项目下所有任务信息 成功", rest, cnt);
        }
        return AjaxResult.error("获取项目下所有任务信息 失败", -1);
    }

    /**
     * 获取任务下所有图斑信息
     *
     * @param param
     * @return
     */
    @Log(title = "获取任务下所有图斑信息", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/queryTbList", method = RequestMethod.POST)
    public AjaxResult queryTbList(@RequestBody Map<String, Object> param) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        param.put("xzqdm", loginUser.getSysUser().getXzqdm());
        List<Map<String, Object>> rest = appService.queryTbList(param);
        Integer cnt = appService.queryTbListCount(param);
        if (rest != null) {
            return AjaxResult.success("获取任务下所有图斑信息 成功", rest, cnt);
        }
        return AjaxResult.error("获取任务下所有图斑信息 失败", -1);
    }

    /*图斑详情*/
    @Log(title = "图斑详情接口", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/queryTbInfo", method = RequestMethod.POST)
    public AjaxResult queryTbInfo(@RequestBody Map<String, Object> param) {
        Map<String, Object> rest = appService.queryTbInfo(param);
        if (rest != null) {
            return AjaxResult.success("图斑详情接口 成功", rest);
        }
        return AjaxResult.error("图斑详情接口 失败", -1);
    }

    /*矢量范围接口*/
    @Log(title = "矢量范围接口", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/queryWKT", method = RequestMethod.POST)
    public AjaxResult queryWKT(@RequestBody Map<String, Object> param) {
        List<Map<String, Object>> rest = appService.queryWKT(param);
        if (rest != null) {
            return AjaxResult.success("矢量范围接口 成功", rest);
        }
        return AjaxResult.error("矢量范围接口 失败", -1);
    }

    /**
     * @param param
     * @return
     */
    @Log(title = "APP提交", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/saveTaskDetailAnnex", method = RequestMethod.POST)
    public AjaxResult saveTaskDetailAnnex(@RequestBody Map<String, Object> param) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        param.put("username", loginUser.getUsername());
        Integer rest = appService.saveTaskDetailAnnex(param);
        if (rest > 0) {
            return AjaxResult.success("APP提交 成功", rest);
        }
        return AjaxResult.error("APP提交 失败", -1);
    }

    public static void deleteFolder(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            if (file.isFile()) {
                file.delete();
                System.out.println("文件删除成功：" + filePath);
            }
        } else {
            System.out.println("文件不存在：" + filePath);
        }
    }


    /*1.7举证结果信息上传*/
//    @Log(title = "1.7举证结果信息上传", businessType = BusinessType.OTHER)

    /*1.8举证照片回显*/
//    @Log(title = "1.8举证照片回显", businessType = BusinessType.OTHER)

    /*1.9其他接口*/
//    @Log(title = "1.9其他接口", businessType = BusinessType.OTHER)


    /**
     * 文件上传
     *
     * @param file
     * @param jcbh
     * @param xzqdm
     * @return
     */
    @Log(title = "文件上传", businessType = BusinessType.OTHER)
    @Transactional
    @RequestMapping(value = "/uploadOBSFile", method = RequestMethod.POST)
    public AjaxResult uploadOBSFile(@RequestParam(value = "file") MultipartFile file,
                                    @RequestParam(value = "jcbh") String jcbh,
                                    @RequestParam(value = "xzqdm") String xzqdm,
                                    @RequestParam(value = "pch") String pch) {
        try {
            if (file == null) {
                return AjaxResult.error("请选择需要上传的文件");
            } else {
                if (!file.isEmpty()) {

                    // 获取文件原本的名字
                    String originName = file.getOriginalFilename();
                    // 判断文件是否是pdf文件
//        Set<String> set = new HashSet<>();
//        set.add(".pdf");
//        set.add(".doc");
//        set.add(".docx");
                    // 取出文件的后缀
                    int count = 0;
                    for (int i = 0; i < originName.length(); i++) {
                        if (originName.charAt(i) == '.') {
                            count = i;
                            break;
                        }
                    }
                    String endName = originName.substring(count); //取出文件类型
                    String fileType = originName.substring(count + 1); //文件类型
//        if (!set.contains(endName)) {
//            return new String("上传的文件类型错误,只能上传pdf,doc,docx类型的文件");
//        }
                    // 创建保存路径
                    String savePath = System.getProperty("user.dir") + "\\" + "appFiles" + "\\" + pch + "\\" + xzqdm + "\\" + jcbh;
                    // 保存文件的文件夹
                    File folder = new File(savePath);
                    // 判断路径是否存在,不存在则自动创建
                    if (!folder.exists()) {
                        folder.mkdirs();
                    }
                    String saveName = originName;

                    //文件存到本地
                    file.transferTo(new File(folder, saveName));
                    //文件地址
                    String filePath = savePath + "\\" + saveName;

                    String OBSAddress = "app" + "/" + pch + "/" + xzqdm + "/" + jcbh + "/" + saveName;
//                    String log = OBSUploadUnits.OBSUpload(OBSAddress, filePath);
                    AtomicInteger attemptCount = new AtomicInteger(0);
                    String log;
                    do {
                        log = OBSUploadUnits.OBSUpload(OBSAddress, filePath);
                        attemptCount.incrementAndGet();
                    } while (!log.equals("success") && attemptCount.get() < 5);

                    deleteFolder(filePath);
                    Map<String, Object> rest = new HashMap<>();
                    if ("success".equals(log)) {
                        String fj = "https://obs-top.obs.cn-north-1.myhuaweicloud.com/" + OBSAddress;
                        rest.put("fj", fj);
                        return AjaxResult.success("文件上传成功", rest);
                    } else {
                        return AjaxResult.error("obs多次尝试上传仍未成功", log);
                    }
                }
                return AjaxResult.error("文件上传失败");
            }
        } catch (Exception ex) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("上传文件异常，请联系管理员" + ex);
        }
    }

    /**
     * 删除文件
     *
     * @param file
     * @param jcbh
     * @param xzqdm
     * @return
     */
    @RequestMapping(value = "/deleteOBSFile", method = RequestMethod.POST)
    public AjaxResult deleteOBSFile(@RequestParam(value = "file") MultipartFile file,
                                    @RequestParam(value = "jcbh") String jcbh,
                                    @RequestParam(value = "xzqdm") String xzqdm,
                                    @RequestParam(value = "pch") String pch) {
        try {
            if (file == null) {
                return AjaxResult.error("请选择需要删除的文件");
            } else {
                if (!file.isEmpty()) {
                    String saveName = file.getOriginalFilename();
                    String OBSAddress = "app" + "/" + pch + "/" + xzqdm + "/" + jcbh + "/" + saveName;
                    OBSDeleteUnits.OBSDelete(OBSAddress);
                }
            }
            return AjaxResult.success("文件删除成功");
        } catch (Exception ex) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("删除文件异常，请联系管理员" + ex);
        }
    }


    /**
     * @param param
     * @return
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public AjaxResult save(@RequestBody Map<String, Object> param) {
        JSONObject s = new JSONObject(param);
        System.out.println(s.toJSONString());
        System.out.println(param.get("fj"));
        Integer rest = appService.save(param);
        if (rest > 0) {
            return AjaxResult.success("保存 成功", rest);
        }
        return AjaxResult.error("保存 失败", -1);
    }

    /**
     * @param param
     * @return
     */
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public AjaxResult delete(@RequestBody Map<String, Object> param) {
        Integer rest = appService.delete(param);
        if (rest > 0) {
            return AjaxResult.success("删除 成功", rest);
        }
        return AjaxResult.error("删除 失败", -1);
    }


    //todo
    //app登陆 可以使用原始登陆接口过滤验证码

    /*获取批次号*/
    @Log(title = "获取批次号", businessType = BusinessType.OTHER)
    @RequestMapping(value = "/getPch", method = RequestMethod.POST)
    public AjaxResult getPch(@RequestBody Map<String, Object> param) {
        List<String> rest = appService.getPch(param);
        if (rest != null) {
            return AjaxResult.success("获取批次号 成功", rest);
        }
        return AjaxResult.error("获取批次号 失败", -1);
    }

    //获取分配给当前用户的所有图斑地块 分页
    //图斑或地块唯一
    @RequestMapping(value = "/queryTaskTbList", method = RequestMethod.POST)
    public AjaxResult queryTaskTbList(@RequestBody Map<String, Object> param) {
        try {
            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
            param.put("userId", loginUser.getUserid());
            List<Map<String, Object>> rest = appService.queryTaskTbList(param);
            Integer cnt = appService.queryTaskTbListCount(param);
            return AjaxResult.success("获取分配给当前用户的所有图斑地块 成功", rest, cnt);
        } catch (Exception e) {
            return AjaxResult.error("获取分配给当前用户的所有图斑地块 失败", e.getMessage().toString());
        }
    }

    //获取图斑详情数据
    @RequestMapping(value = "/queryTbDetails", method = RequestMethod.POST)
    public AjaxResult queryTbDetails(@RequestBody Map<String, Object> param) {
        try {
            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
            param.put("userId", loginUser.getUserid());
            Map<String, Object> rest = appService.queryTbDetails(param);
            return AjaxResult.success("获取图斑详情数据 成功", rest);
        } catch (Exception e) {
            return AjaxResult.error("获取图斑详情数据 失败", e.getMessage().toString());
        }
    }

    //通过照片id返回照片二进制 list
    @RequestMapping(value = "/getFileStreamById", method = RequestMethod.POST)
    public AjaxResult getFileStreamById(@RequestBody Map<String, Object> param) {
        try {
            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
            List<Map<String, Object>> rest = appService.getFileStreamById(param);
            return AjaxResult.success("获取数据 成功", rest);
        } catch (Exception e) {
            return AjaxResult.error("获取数据 失败", e.getMessage().toString());
        }
    }

    //提交信息
    @RequestMapping(value = "/submitInfo", method = RequestMethod.POST)
    public AjaxResult saveInfo(@RequestBody Map<String, Object> param) {
        try {
            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
            param.put("userId", loginUser.getSysUser().getUserId());
            param.put("userName", loginUser.getSysUser().getUserName());
            param.put("nickName", loginUser.getSysUser().getNickName());
            String rest = appService.saveInfo(param);
            return AjaxResult.success("提交信息", rest);
        } catch (Exception e) {
            return AjaxResult.error("提交信息 失败", e.getMessage().toString());
        }
    }

    @Transactional
    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    public AjaxResult uploadFile(@RequestParam(value = "fileList") List<MultipartFile> fileList,
                                 @RequestParam(value = "dkbh") String dkbh,
                                 @RequestParam(value = "xzqdm") String xzqdm,
                                 @RequestParam(value = "pch") String pch) {
        try {
            Integer rest = 0;
            for (MultipartFile file : fileList) {
                if (file == null) {
                    return AjaxResult.error("上传文件有误！");
                } else {
                    if (!file.isEmpty()) {
                        String saveName = file.getOriginalFilename();

                        // 创建保存路径
                        String savePath = System.getProperty("user.dir") + "\\" + "appFiles" + "\\" + pch + "\\" + xzqdm + "\\" + dkbh;
                        // 保存文件的文件夹
                        File folder = new File(savePath);
                        // 判断路径是否存在,不存在则自动创建
                        if (!folder.exists()) {
                            folder.mkdirs();
                        }
                        //文件存到本地
                        file.transferTo(new File(folder, saveName));
                        //文件地址
                        String filePath = savePath + "\\" + saveName;

                        String OBSAddress = "app" + "/" + pch + "/" + xzqdm + "/" + dkbh + "/" + saveName;
                        AtomicInteger attemptCount = new AtomicInteger(0);
                        String log;
                        do {
                            log = OBSUploadUnits.OBSUpload(OBSAddress, filePath);
                            attemptCount.incrementAndGet();
                        } while (!log.equals("success") && attemptCount.get() < 5);

                        deleteFolder(filePath);
                        Map<String, Object> map = new HashMap<>();
                        if ("success".equals(log)) {
//                            String fj = "https://obs-top.obs.cn-north-1.myhuaweicloud.com/" + OBSAddress;
//                            map.put("fj", fj);
                            rest++;
                        } else {
                            return AjaxResult.error(saveName + "obs多次尝试上传仍未成功", log);
                        }
                    } else {
                        return AjaxResult.error("上传文件不能为空！");
                    }
                }
            }
            return AjaxResult.success("文件上传成功", rest);
        } catch (Exception ex) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("上传文件异常，请联系管理员" + ex);
        }
    }

    //获取App版本
    @RequestMapping(value = "/getVersion", method = RequestMethod.POST)
    public AjaxResult getVersion(@RequestBody Map<String, Object> param) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        String rest = appService.getVersion(param);
        return AjaxResult.success("获取App版本 成功", rest);
    }

    //更新App版本
    @RequestMapping(value = "/updateVersion", method = RequestMethod.POST)
    public AjaxResult updateVersion(@RequestBody Map<String, Object> param) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        Integer rest = appService.updateVersion(param);
        if (rest > 0) {
            return AjaxResult.success("更新App版本 成功", rest);
        } else {
            return AjaxResult.success("更新App版本 失败", rest);
        }
    }

    //保存app日志
    @RequestMapping(value = "/saveLog", method = RequestMethod.POST)
    public AjaxResult saveLog(@RequestBody Map<String, Object> param,HttpServletRequest request) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        param.put("user_id",loginUser.getUserid());
        param.put("user_name",loginUser.getSysUser().getUserName());
        param.put("nick_name",loginUser.getSysUser().getNickName());
        param.put("ip",getClientIp(request));
        param.put("submitdate", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((new Date()).getTime()));
        Integer rest = appService.saveLog(param);
        if (rest > 0) {
            return AjaxResult.success("保存app日志 成功", rest);
        } else {
            return AjaxResult.success("保存app日志 失败", rest);
        }
    }

    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 如果通过多个代理，可能会获取到多个IP，取第一个非unknown的IP
        if (ip.contains(",")) {
            String[] ips = ip.split(",");
            for (String s : ips) {
                if (!"unknown".equalsIgnoreCase(s)) {
                    ip = s;
                    break;
                }
            }
        }
        return ip;
    }

}
